﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.CommonBot;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt;
using WingIt.Dynamics;
using WingIt.Routines;
using WingIt.Routines.Mirrors;

using Action = Buddy.BehaviorTree.Action;


namespace WingIt
{
    [RevisionControlId("$Id: WingIt.cs 686 2012-08-12 16:12:20Z Chinajade $")]
    public class WingIt : CombatRoutine
    {
        private Composite _ooc;
        private Composite _pull;
        private Composite _combat;

        public AdvancedClass AdvancedClass { get { return BuddyTor.Me.AdvancedClass; } }
        public SkillTreeId PrimarySpec { get { return BuddyTor.Me.PrimarySpec(); } }

        public static CombatRoutine Instance { get; set; }
        public static CharacterClass MyNormalizedClass = CharacterClass.Unknown;
        public static CharacterClass MyNormalizedMirrorClass = CharacterClass.Unknown;
        public static AdvancedClass PreviousAdvancedClass = BuddyTor.Me.AdvancedClass;
        public static SkillTreeId PreviousPrimarySpec = BuddyTor.Me.PrimarySpec();

        #region Overrides of CombatRoutine

        public override string Name { get { return "WingIt - All In One"; } }

        public override Window ConfigWindow { get { return null; } }

        public override CharacterClass Class { get { return BuddyTor.Me.Class; } }

        public override Composite OutOfCombat { get { return _ooc; } }

        public override Composite Pull { get { return _pull; } }

        public override Composite Combat { get { return _combat; } }

        public override void Dispose()
        {
            // empty (for now)
        }

        public override void Initialize()
        {
            //Logger.Write("Name: " + BuddyTor.Me.Name);
            //Logger.Write("Acc-Name: " + BuddyTor.Client.AccountName);
            Logger.Write("Level: " + BuddyTor.Me.Level);
            Logger.Write("Class: " + Class);
            Logger.Write("Advanced Class: " + AdvancedClass + " ( " + BuddyTor.Me.PrimarySpec().ToString().Replace(AdvancedClass.ToString(), "") + " )");
            Logger.Write("Talent build: {0}", SpecHandler.TalentBuild(BuddyTor.Me));
            Instance = this;

            MyNormalizedClass = BuddyTor.Me.NormalizedClass();
            MyNormalizedMirrorClass = Mirror.GetMirrorClass(MyNormalizedClass);
            Mirror.Initialize(MyNormalizedClass, MyNormalizedMirrorClass);

            _ooc = new PrioritySelector(
                        CreateBTPS.ToonAndCompanionRejuvenate(),
                        CreateBTPS.ReviveAndRebuffPartyMembers_OutOfCombat(),
                        CreateBTPS.ToonSelfBuff(),
                        new Decorator(notMountedWhen => !BuddyTor.Me.IsMounted,
                            CreateBTPS.DriveByLove()),
                        CreateBTPS.ReloadWingIt()
                        );
            
            int count;

            _pull = CompositeBuilder.GetComposite(Class, AdvancedClass, PrimarySpec, BehaviorType.Pull, out count);
            if (count == 0 || _pull == null)
            {
                Logger.Write("Pull support for " + Class + " [" + PrimarySpec + "] is not currently implemented.");
            }
            _combat = CompositeBuilder.GetComposite(Class, AdvancedClass, PrimarySpec, BehaviorType.Combat, out count);
            if (count == 0 || _combat == null)
            {
                Logger.Write("Combat support for " + Class + " [" + PrimarySpec + "] is not currently implemented.");
                BotMain.Stop();
            }

            if (_combat != null && _pull == null)
            {
                _pull = _combat;
                Logger.Write("Using Combat for Pull.");
            }
            else if (_pull == null)
            {
                BotMain.Stop();
                Logger.Write("Buddy Wing stopped!");
            }

            var extraOoc = CompositeBuilder.GetComposite(Class, AdvancedClass, PrimarySpec, BehaviorType.OutOfCombat, out count);
            // Add the extra logic for OOC stuff from the combat declaration.
            if (extraOoc != null && count > 0)
                (_ooc as PrioritySelector).AddChild(extraOoc);

            HookOnBotStartStop();
            LazyRaider.Initialize();

            Logger.Write("WingIt Subversion revision: {0}", RevisionControl.GetRevision());
        }

        #endregion      // Overrides of CombatRoutine

        #region Bot stop/start handling
        private static void     HookOnBotStartStop()
        {
            // Since BuddyWing likes to initialize WingIt more than once, we must first remove
            // any previous installation of stop/start handlers that may be laying about from
            // previous initialiations.
            BotMain.OnStart -= LazyRaider.BotEvent_OnBotStart;
            BotMain.OnStop -= LazyRaider.BotEvent_OnBotStop;

            // Reinstall the handlers...
            BotMain.OnStart += LazyRaider.BotEvent_OnBotStart;
            BotMain.OnStop += LazyRaider.BotEvent_OnBotStop;
        }

        #endregion

        /*private Composite RepairOnField()
{
    return new Decorator(whenRepairBotDeployNeeded => BuddyTor.Me.InventoryEquipped.Count(i => i.DurabilityPercent <= 100) >= 1 && 
                                Me.HasMirrorAbility("Deploy Field Repair Droid") && 
                                Me.CanMirrorCast("Deploy Field Repair Droid", BuddyTor.Me),
                                new Sequence(
                                    new Action(deployRepairBot => Spell.Cast("Deploy Field Repair Droid")),
                                    new Action(interactWithRepairBot => ObjectManager.GetObjects<Buddy.Swtor.Objects.TorNpc>().FirstOrDefault(o => o.Name == "Field Repair Droid").Interact())
                                    )                                            
        );
}*/
    }
}